package itsm.isperp.module.controller.api.wechat;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.domain.UploadInfo;
import itsm.isperp.framework.service.UploadFileService;
import itsm.isperp.framework.template.Template;
import itsm.isperp.framework.template.TemplateException;
import itsm.isperp.framework.utils.DateUtils;
import itsm.isperp.framework.utils.FileUploadUtils;
import itsm.isperp.module.dto.app.ChatMessage;
import itsm.isperp.module.entity.wechat.WechatNewsArticle;
import itsm.isperp.module.entity.wechat.cp.WechatCpMenu;
import itsm.isperp.module.service.wechat.WechatNewsArticleService;
import itsm.isperp.module.service.wechat.cp.WechatCpMenuService;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item;
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 微信
 * 
 * @author zhouhg
 * @date 2014-3-11
 * @version V1.0
 */
@Controller
@RequestMapping("api/wechat/cp")
public class WechatCpController {

	public static final Logger logger = LoggerFactory
			.getLogger(WechatCpController.class);

	@Autowired
	WxCpService wxCpService;

	@Autowired
	SimpMessagingTemplate simpMessagingTemplate;

	@RequestMapping(value = "/main")
	public void coreJoinPost(HttpServletRequest request,
			HttpServletResponse response) throws IOException, TemplateException {
		response.setContentType("text/html;charset=utf-8");
		response.setStatus(HttpServletResponse.SC_OK);

		// 调用核心业务类接收消息、处理消息
		// 微信加密签名8
		String msg_signature = request.getParameter("msg_signature");
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		// 随机数
		String nonce = request.getParameter("nonce");
		// 随机字符串
		String echostr = request.getParameter("echostr");

		// InputStream is = request.getInputStream();
		// String postData = IOUtils.toString(is, "UTF-8");
		WxCpConfigStorage wxCpConfigStorage = ContextHolder.getWxCpConfig();

		if (StringUtils.isNotBlank(echostr)) {
			if (!wxCpService.checkSignature(msg_signature, timestamp, nonce,
					echostr)) {
				// 消息签名不正确，说明不是公众平台发过来的消息
				response.getWriter().println("非法请求");
				return;
			}
			WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage);
			String plainText = cryptUtil.decrypt(echostr);
			// 说明是一个仅仅用来验证的请求，回显echostr
			response.getWriter().println(plainText);
			return;
		}

		WxCpXmlMessage xml = WxCpXmlMessage.fromEncryptedXml(
				request.getInputStream(), wxCpConfigStorage, timestamp, nonce,
				msg_signature);

		WxCpXmlOutMessage outMessage = null;
		final String url = ContextHolder.getWebServerName();
		switch (xml.getMsgType()) {
		case WxConsts.XML_MSG_EVENT:

			WechatCpMenuService wechatCpMenuService = ContextHolder
					.getSpringBean("wechatCpMenuService");

			WechatCpMenu menu = wechatCpMenuService.findOneByKey(xml
					.getEventKey());

			String replayType = menu.getReplayType();

			switch (replayType) {

			case "text":
				outMessage = generalTextMessage(xml, url,
						menu.getMessageContent());

				break;

			case "news":
				outMessage = generalNewsMessage(xml, url, menu.getNewsId());
				break;
			}
			break;

		case WxConsts.XML_MSG_TEXT:
			sendChat(xml, xml.getContent());
			break;
		case WxConsts.XML_MSG_IMAGE:
		case WxConsts.XML_MSG_VOICE:

			File file = null;
			try {
				file = wxCpService.mediaDownload(xml.getMediaId());
			} catch (WxErrorException e1) {
				outMessage = generalTextMessage(xml, url, "您发送到服务器的文件无法接收！");
			}

			String msgTypeName = "";
			UploadInfo uploadInfo = null;
			String fileNameExt = "";
			if (WxConsts.XML_MSG_IMAGE.equals(xml.getMsgType())) {
				msgTypeName = "图片";
				fileNameExt = "png";

			} else if (WxConsts.XML_MSG_VOICE.equals(xml.getMsgType())) {
				msgTypeName = "语音";
				fileNameExt = "amr";

			} else if (WxConsts.XML_MSG_VIDEO.equals(xml.getMsgType())) {
				msgTypeName = "视频";
				fileNameExt = "mp4";

			}

			try {
				uploadInfo = FileUploadUtils.persist(file, fileNameExt,
						msgTypeName);

				uploadInfo.setMeno(xml.getMediaId());
				UploadFileService<UploadInfo> uploadFileService = ContextHolder
						.getSpringBean("appUploadFileService");

				uploadFileService.saveOrUpdate(uploadInfo);

			} catch (IOException e) {
				logger.error(e.getMessage(), e);

				outMessage = generalTextMessage(xml, url, "您发送到服务器的文件无法保存！");

			}

			sendChat(xml, uploadInfo.getPath());

			break;
		default:
			WxCpXmlOutTextMessage out = new WxCpXmlOutTextMessage();
			out.setContent("不支持此类型操作，请返回菜单！");
			out.setFromUserName(ContextHolder.getWxCpConfig().getCorpId());
			out.setToUserName(xml.getFromUserName());
			outMessage = out;
			break;

		}

		if (outMessage != null) {
			outMessage.setCreateTime(new Date().getTime());
			
			logger.info("Gaotest:outMessageInfo:"+outMessage.toEncryptedXml(ContextHolder.getWxCpConfig()));
			logger.info("Gaotest:outMessageInfo:"+outMessage);
			response.getWriter().print(
					outMessage.toEncryptedXml(ContextHolder.getWxCpConfig()));
		}
	}

	private void sendChat(WxCpXmlMessage xml, String data) {

		ChatMessage message = new ChatMessage();

		message.setSuccess(true);
		message.setOpenid(xml.getFromUserName());
		message.setMsgType(xml.getMsgType());
		message.setSenderName("");
		message.setSendTime(DateUtils.DF_LONG_LONG.format(xml.getCreateTime()));
		message.setData(data);

		simpMessagingTemplate.convertAndSend("/chatMessage/result", message);
	}

	/**
	 * 
	 * @param msg
	 * @param url
	 * @param messageContent
	 * @return
	 */
	public static WxCpXmlOutTextMessage generalTextMessage(WxCpXmlMessage msg,
			String url, String messageContent) {

		WxCpXmlOutTextMessage message = new WxCpXmlOutTextMessage();

		message.setFromUserName(ContextHolder.getWxCpConfig().getCorpId());
		message.setToUserName(msg.getFromUserName());
		// 在配置中取得信息
		Map<String, Object> vars = new HashMap<String, Object>();

		vars.put("config", ContextHolder.CONFIG_RESOURCES_MAP);
		vars.put("openid", msg.getFromUserName());
		vars.put("contextUrl", url);

		Template template = new Template(messageContent);
		template.setContext(vars);

		try {
			message.setContent(template.render());
		} catch (Exception e) {

			message.setContent("服务器错误！");
		}

		return message;
	}

	public static WxCpXmlOutNewsMessage generalNewsMessage(WxCpXmlMessage msg,
			String url, String newsId) throws TemplateException {
		WxCpXmlOutNewsMessage message = new WxCpXmlOutNewsMessage();
		message.setFromUserName(msg.getToUserName());
		message.setToUserName(msg.getFromUserName());
		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("config", ContextHolder.CONFIG_RESOURCES_MAP);
		vars.put("openid", msg.getFromUserName());
		vars.put("contextUrl", url);
		
		

		WechatNewsArticleService wechatNewsArticleService = ContextHolder
				.getSpringBean("wechatNewsArticleService");
		List<WechatNewsArticle> articles = null;
		try {
      String openId=msg.getFromUserName();
			articles = wechatNewsArticleService.findByNewsId(newsId,openId);

		} catch (Exception e) {
			articles = new ArrayList<>();
			WechatNewsArticle article = new WechatNewsArticle();
			article.setTitle("谢谢关注!");

			articles.add(article);
		}

		for (WechatNewsArticle article : articles) {
			Item item = new Item();
			item.setDescription(article.getDescription());
			item.setPicUrl(url + article.getPicurl());
			item.setTitle(article.getTitle());
			String ctUrl=article.getUrl();
			if(StringUtils.isNotBlank(ctUrl))
			{
				Template template = new Template(ctUrl);
				template.setContext(vars);
				String test=template.render();
				if(StringUtils.isNotBlank(test))
				item.setUrl(test);
				//logger.info("GaotestInfo2:"+template.render());
				message.addArticle(item);
				
			}else
			{
				item.setUrl("");
				message.addArticle(item);
			}
			
		}

		// 在配置中取得信息

		return message;

	}
}
